<template>
    <div>
        <h1>使用 ref 进行绑定</h1>
        <div>数字1：<input type="submit" v-model="No1"> </div>
        <br>
        <div>数字2：<input type="submit" v-model="No2"> </div>   
        <br> 
        <div>求和：<input type="submit" v-model="Sum01"> </div> 
        <br>             
        <button @click="Click01">按钮</button>
        <br>   
        <h1>使用 reactive 进行绑定</h1>
        <div>数字21：<input type="submit" v-model="No21"> </div>
        <br>
        <div>数字22：<input type="submit" v-model="No22"> </div>   
        <br> 
        <div>求和：<input type="submit" v-model="Sum01"> </div> 
        <br>             
        <button @click="Click02">按钮2</button>
        <br>
        <button @click="Click03">调用子组件方法</button>
        <br>
        <moS ref="moSon"></moS>
        

    </div>
</template>

<script lang = 'ts'>
    import { ref , toRefs , reactive,computed,watch,defineComponent} from 'vue';
    import moS from './study002.vue'

    interface User{
        username:string,
        age:number,
        setUserName():void;
        getUserName?():void;
    }

    export default defineComponent({
        name:"study001",
        components:{                                             //引入子组件
            moS
        },
        setup(){

            //基础变量类型绑定（bool,number，String)
            const No1 = ref(1);                                  //ref 也支持复杂对象的绑定，但不推荐使用
            const No2 = ref(2);

            const Click01 = () => {
                No1.value ++ ;                                  //ref 绑定的变量，赋值操作需要 变量名.value
                No2.value += 3;
            }

            const Sum01 = computed(()=>{                        //计算脚本，会自动监控表达式对应的变化并更新值。复杂脚本请用 Watch
                return No1.value + No2.value ;
            });

            watch([No1,No2],(newValue,oldValue) => {            // watch(监控变量,CallBack(新值,旧值)),需要监控多个变量时，用数组传入
                let str = "No1/No2的数值发生变化\n";
                str += "No1 旧值= " + oldValue[0] + ", 新值= " + newValue[0] + " \n" ;
                str += "No2 旧值= " + oldValue[1] + ", 新值= " + newValue[1] + " \n" ;
                console.log(str);
            });


            //-----------对象变量绑定---------
            let No21 = 0 ;
            let No22 = 0 ;
            const obj =  reactive({No21,No22});                 //复杂，深层次的变量，需要用reactive绑定
            const Click02 = () => {
                obj.No21 ++ ;                                   //reactive 绑定操作不需要 value
                obj.No22 += 3;
            }


            watch(obj,(newValue,oldValue) => {                  // watch 监控对象变量时，是无法获取旧值的
                let str = "obj 的数值发生变化，但无法监测旧值\n";
                console.log(str);
                console.log(newValue);
                console.log(oldValue);                           //这里的 oldValue 也是等于新值
            });

            watch(() => obj.No21,(newValue,oldValue) => {        //监控对象单一属性时，可以获取旧值，但参数的改为 ()=>对象.属性
                let str = "只监测No21，可以获取新旧值\n";
                console.log(str);
                console.log(newValue);
                console.log(oldValue);
            }); 
            //---------调用子模块的方法（传参）
            var moSon = ref();  //注意不能给初值
            const Click03 = ()=>{
                moSon.value.SunPrint('父组件调用');
            }

            //---------返回给视图层------------
            return {
                No1,
                No2,
                Sum01,
                Click01,
                Click02,
                ...toRefs(obj),  //使用 toRefs 能在视图层减少一级，如 obj,No22 ，在视图层只用 N022 就可以使用 
                Click03,
                moSon
            }

        }
    });



</script>

